
package info.lvcoffee.ethernethelper;


import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.sufficientlysecure.rootcommands.RootCommands;
import org.sufficientlysecure.rootcommands.Shell;
import org.sufficientlysecure.rootcommands.command.SimpleCommand;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.util.Log;

public class Utils{
	  private final String TAG="Utils";
	  private  String  PREF_FILE_NAME="ethernethelper";
	  
	  private static Utils INSTANCE=null;
	  
	  public static Utils getInstance()
	  {
		  RootCommands.DEBUG = true;
		  if(INSTANCE==null)
			  INSTANCE=new Utils();
			  
		  return INSTANCE;
	  }
	  
	  public  List<NetInterfaceInfo> getNetInterface()
	  {
		    List<NetInterfaceInfo> lstUpNetInterface=new ArrayList<NetInterfaceInfo>();
	    	try
			{
/*				Process process = Runtime.getRuntime().exec("su");
				DataOutputStream os = new DataOutputStream(process.getOutputStream());
				DataInputStream is = new DataInputStream(process.getInputStream());
				os.writeBytes("netcfg\n");
				os.writeBytes("exit\n");
				os.flush();	
				String strIs=is.readLine();*/
	    		
	    		Shell rootShell = Shell.startRootShell();

	            // simple commands
	            SimpleCommand cmdNetcfg = new SimpleCommand("netcfg");
	            rootShell.add(cmdNetcfg).waitForFinish();
	            if(cmdNetcfg.getExitCode()!=0)
				{
					cmdNetcfg = new SimpleCommand("/data/data/info.lvcoffee.ethernethelper/netcfg");
					rootShell.add(cmdNetcfg).waitForFinish();
				}
	            String strIs=cmdNetcfg.getOutput();
	            rootShell.close();
	        
	            String lines[]=strIs.split("\n");
			//	while(strIs!=null)
	            for(String line:lines)
				{
					String[] strIfItem= line.split("\\s+");
					if((strIfItem.length==5)/*&&(strIfItem[1].equals("UP"))*/&&
							    (!strIfItem[0].equals("lo")))
					{
						NetInterfaceInfo ifItem=new NetInterfaceInfo();
						ifItem.setIfName(strIfItem[0]);
						ifItem.setIfState(strIfItem[1]);
						ifItem.setIfIpAddr(strIfItem[2].split("/")[0]);
						ifItem.setIfNetPrefLen(strIfItem[2].split("/")[1]);
						ifItem.setIfMac(strIfItem[4]);
						lstUpNetInterface.add(ifItem);
						Utils.debug("Utils","add interface "+strIfItem[0]);
						
					}
					//strIs=is.readLine();				
				}
			}
			catch (Exception e)
			{
				Utils.error("Utils","getNetInterface "+e.getMessage());
			}			
		    return lstUpNetInterface;
	  }

	  
	  /**
	   * 开启有线网卡
	   * @param eth
	   * @param bIsDhcp
	   * @return true: 开启成功
	   */    
	  
	  public  boolean enableEthernet(String eth, boolean bIsDhcp)
	  {
		    boolean bSuccess=false;
	    	try
			{
/*				Process process = Runtime.getRuntime().exec("su");
				DataOutputStream os = new DataOutputStream(process.getOutputStream());
				//DataInputStream is = new DataInputStream(process.getInputStream());
				os.writeBytes("netcfg  "+eth+"  up\n");
				if(bIsDhcp)
					os.writeBytes("netcfg  "+eth+"  dhcp\n");
				os.writeBytes("exit\n");
				os.flush();	*/
	    		
	       		Shell rootShell = Shell.startRootShell();

	            // simple commands
	            SimpleCommand cmdNetcfg = new SimpleCommand("netcfg  "+eth+"  dhcp");
	            rootShell.add(cmdNetcfg).waitForFinish();
				if(cmdNetcfg.getExitCode()!=0)
				{
					cmdNetcfg = new SimpleCommand("/data/data/info.lvcoffee.ethernethelper/netcfg  "+eth+"  dhcp");
					rootShell.add(cmdNetcfg).waitForFinish();
				}

	            if(cmdNetcfg.getExitCode()==0)
	        	   bSuccess=true;
	           
	            rootShell.close();
	        			
			
			}
			catch (Exception e)
			{
				Utils.error("Utils","getNetInterface "+e.getMessage());
			}			
		    return bSuccess;
	  }
	  
	  /**
	   * 设置静态IP
	   * @param eth
	   * @param ipAddr
	   * @param netMask
	   * @param gateWay
	   * @return true: 开启成功
	   */    
	  
	  public  boolean setStaticIp(String eth, String ipAddr, String netMask ,String gateWay)
	  {
		    boolean bSuccess=false;
	    	try
			{
/*				Process process = Runtime.getRuntime().exec("su");
				DataOutputStream os = new DataOutputStream(process.getOutputStream());
				//ifconfig eth0 192.168.1.2 netmask 255.255.255.0
				os.writeBytes("ifconfig  "+eth+" "+ipAddr+" netmask "+netMask+"\n");
				//route add default gw 192.168.1.1 dev eth0
				os.writeBytes("route add default gw "+gateWay+" dev "+eth+"\n");
				os.writeBytes("exit\n");
				os.flush();	*/

	       		Shell rootShell = Shell.startRootShell();

	            // simple commands
	            SimpleCommand cmdIfconfig = new SimpleCommand("ifconfig  "+eth+" "+ipAddr+
	            									" netmask "+netMask);
	            SimpleCommand cmdRoute = new SimpleCommand("route add default gw "+gateWay+" dev "+eth);	            
	            rootShell.add(cmdIfconfig).waitForFinish();
	            rootShell.add(cmdRoute).waitForFinish();
	            if((cmdIfconfig.getExitCode()==0)&&(cmdRoute.getExitCode()==0))
	        	   bSuccess=true;
	           
	            rootShell.close();
			}
			catch (Exception e)
			{
				Utils.error("Utils","setStaticIp "+e.getMessage());
			}			
		    return bSuccess;
	  }
	  
	  
	  public  void writeEthInterface(Context context, String eth)
	  {
		   SharedPreferences sharePref=context.getSharedPreferences(PREF_FILE_NAME,Context.MODE_PRIVATE);
		   Editor edit=sharePref.edit();
		   edit.putString("interface", eth);
		   edit.commit();
	       return ;
	  }
	  
	  
	  public  String readEthInterface(Context context)
	  {
		   SharedPreferences sharePref=context.getSharedPreferences(PREF_FILE_NAME,Context.MODE_PRIVATE);
		   String strInterface=sharePref.getString("interface", "");
	       return strInterface;
	  }
	  
	  public String getNetMask(String eth)
	  {
		  String mask="0.0.0.0";
		  
		  try
		  {
/*				Process process = Runtime.getRuntime().exec("su");
				DataOutputStream os = new DataOutputStream(process.getOutputStream());
				DataInputStream is = new DataInputStream(process.getInputStream());
				os.writeBytes("ifconfig  "+eth+"  \n");
				os.writeBytes("exit\n");
				os.flush();	
				String strIs=is.readLine();*/
				
	    		Shell rootShell = Shell.startRootShell();

	            SimpleCommand cmdIfconfig = new SimpleCommand("ifconfig  "+eth);
	            rootShell.add(cmdIfconfig).waitForFinish();
	            String strIs=cmdIfconfig.getOutput();
	            rootShell.close();
	            
				String[] strArray=strIs.split("\\s+");
			    if(strArray.length>5)
			    {
			    	mask=strArray[4];
			    	if(!checkIpValid(mask))
			    		 mask="0.0.0.0";
			    }
		  }
		  catch (Exception e)
		  {
			Utils.error("Utils","getNetMask "+eth+" "+e.getMessage());
		  }			
		    
		  return mask;
	  }
	  
	  public void enableNetAdb()
	  {
			try
			{
/*				Process process = Runtime.getRuntime().exec("su");
				DataOutputStream os = new DataOutputStream(process.getOutputStream());
			//	DataInputStream is = new DataInputStream(process.getInputStream());
				os.writeBytes("setprop service.adb.tcp.port 5555 \n");
				os.writeBytes("stop  adbd\n ");
				os.writeBytes("start adbd\n");
				os.writeBytes("exit\n");
				os.flush();		*/		

	    		Shell rootShell = Shell.startRootShell();

	            SimpleCommand cmdSetprop = new SimpleCommand("setprop service.adb.tcp.port 5555");
	            SimpleCommand cmdStop = new SimpleCommand("stop  adbd");
	            SimpleCommand cmdStart = new SimpleCommand("start adbd");
	            rootShell.add(cmdSetprop).waitForFinish();
	            rootShell.add(cmdStop).waitForFinish();
	            rootShell.add(cmdStart).waitForFinish();
	            rootShell.close();
			}
			catch (Exception e)
			{
				Utils.error("Utils","enableNetAdb "+e.getMessage());
			}			  
	  }
	  
	  public  boolean isEnableNetAdb()
	  {
		  boolean bEnable=false;
		  
		  try
			{
/*				Process process = Runtime.getRuntime().exec("su");
				DataOutputStream os = new DataOutputStream(process.getOutputStream());
				DataInputStream is = new DataInputStream(process.getInputStream());
				os.writeBytes("getprop service.adb.tcp.port\n");
				os.writeBytes("exit\n");
				os.flush();	*/
				
	    		Shell rootShell = Shell.startRootShell();

	            SimpleCommand cmdGetprop = new SimpleCommand("getprop service.adb.tcp.port");
	            rootShell.add(cmdGetprop).waitForFinish();
	            rootShell.close();
	            
	            if(trimEnter(cmdGetprop.getOutput()).equals("5555"))
				//if(is.readLine().equals("5555"))
					bEnable=true;
			
			}
			catch (Exception e)
			{
				Utils.error("Utils","getNetInterface "+e.getMessage());
			}	
		  
		  return bEnable;
	  }
	
	  
	  public void setDNS(String eth)
	  {
		  String dns1="0.0.0.0";
		  String dns2="0.0.0.0";
		  try
			{	
	    		Shell rootShell = Shell.startRootShell();
	    		//get dns1
	            SimpleCommand cmdGetpropDNS1 = new SimpleCommand("getprop net."+eth+".dns1");
	            rootShell.add(cmdGetpropDNS1).waitForFinish();
	            
	            if(!checkIpValid(trimEnter(cmdGetpropDNS1.getOutput())))
	            {
	                SimpleCommand cmdGetDNS1 = new SimpleCommand("getprop net.dns1");
		            rootShell.add(cmdGetDNS1).waitForFinish();
		            if(checkIpValid(trimEnter(cmdGetDNS1.getOutput())))
		            	dns1=trimEnter(cmdGetDNS1.getOutput());
	            }
	            else
	            	dns1=trimEnter(cmdGetpropDNS1.getOutput());
	            
	            //get dns2
	            SimpleCommand cmdGetpropDNS2 = new SimpleCommand("getprop net."+eth+".dns2");
	            rootShell.add(cmdGetpropDNS2).waitForFinish();
	            
	            if(!checkIpValid(trimEnter(cmdGetpropDNS2.getOutput())))
	            {
	                SimpleCommand cmdGetDNS2 = new SimpleCommand("getprop net.dns2");
		            rootShell.add(cmdGetDNS2).waitForFinish();
		            if(checkIpValid(trimEnter(cmdGetDNS2.getOutput())))
		            	dns2=trimEnter(cmdGetDNS2.getOutput());
	            }
	            else
	            	dns2=trimEnter(cmdGetpropDNS2.getOutput());
	            
	            rootShell.close();
	            
			
			}
			catch (Exception e)
			{
				Utils.error("Utils","setDNS "+e.getMessage());
			}	
		  
           if(Build.VERSION.SDK_INT==VERSION_CODES.KITKAT)
        	   setDNSKitKat(eth,dns1,dns2);
           else if(Build.VERSION.SDK_INT<VERSION_CODES.KITKAT)
        	   setDNSBeforeKitKat(eth,dns1,dns2);
           else if (Build.VERSION.SDK_INT>VERSION_CODES.KITKAT)
        	   setDNSAfterKitKat(eth,dns1,dns2);
	
	  }
	  
	  public void setDNSBeforeKitKat(String eth, String dns1, String dns2)
	  {
		  try
			{	
	    		Shell rootShell = Shell.startRootShell();

	            SimpleCommand cmdSetDNS1 = new SimpleCommand("setprop net.dns1 "+dns1);
	            SimpleCommand cmdSetEthDNS1 = new SimpleCommand("setprop net."+eth+"dns1 "+dns1);
	            SimpleCommand cmdSetDNS2 = new SimpleCommand("setprop net.dns2 "+dns2);
	            SimpleCommand cmdSetEthDNS2 = new SimpleCommand("setprop net."+eth+"dns2 "+dns2);
	            
	            rootShell.add(cmdSetDNS1).waitForFinish();
	            rootShell.add(cmdSetEthDNS1).waitForFinish();
	            rootShell.add(cmdSetDNS2).waitForFinish();
	            rootShell.add(cmdSetEthDNS2).waitForFinish();
	            rootShell.close();	            
			
			}
			catch (Exception e)
			{
				Utils.error("Utils","setDNSBeforeKitKat "+e.getMessage());
			}			  
	  }
	  
	  public void setDNSKitKat(String eth, String dns1, String dns2)
	  {
		  try
			{	
	    		Shell rootShell = Shell.startRootShell();

	            SimpleCommand cmd1 = new SimpleCommand("ndc resolver flushif "+eth);
	            SimpleCommand cmd2 = new SimpleCommand("ndc resolver flushdefaultif");
	            SimpleCommand cmd3 = new SimpleCommand("ndc resolver setifdns  "+eth+
	            											"  0.0.0.0  "+dns1+"  "+dns2);
	            SimpleCommand cmd4 = new SimpleCommand("ndc resolver setdefaultif  "+eth);
	            
	            rootShell.add(cmd1).waitForFinish();
	            rootShell.add(cmd2).waitForFinish();
	            rootShell.add(cmd3).waitForFinish();
	            rootShell.add(cmd4).waitForFinish();
	            rootShell.close();	            
			
			}
			catch (Exception e)
			{
				Utils.error("Utils","setDNSBeforeKitKat "+e.getMessage());
			}			  		  
	  }
	  
	  public void setDNSAfterKitKat(String eth, String dns1, String dns2)
	  {
		  try
			{	
	    		Shell rootShell = Shell.startRootShell();

	            SimpleCommand cmd1 = new SimpleCommand("ndc resolver setnetdns "
	            										+eth+" "+dns1+" "+dns2);
	            SimpleCommand cmd2 = new SimpleCommand("ndc resolver flushnet "+eth);
	            
	            rootShell.add(cmd1).waitForFinish();
	            rootShell.add(cmd2).waitForFinish();

	            rootShell.close();	            
			
			}
			catch (Exception e)
			{
				Utils.error("Utils","setDNSAfterKitKat "+e.getMessage());
			}			  
	  }
	  
	  
	  public static boolean checkIpValid(String ip)
	  {
		  String[] ipArray=ip.split("\\.");
		  if((ipArray.length!=4)&&(ipArray.length!=6))
			  return false;
		  
		  try{
			  for(String val:ipArray)
				  if(Integer.parseInt(val)>255)
					  return false;
		  }
		  catch(NumberFormatException e )
		  {
			  return false;
		  }
		  return true;
	  }
	  
	  public static String trimEnter(String inStr)
	  {
		  String str=inStr;
		  while(str.startsWith("\n"))
			  str=inStr.substring(1);
		  
		  while(str.endsWith("\n"))
			  str=inStr.substring(0, str.length()-1);
		  
		  return str;
	  }

	  public boolean hasNetcfg(){

		try {
			File netcfg = new File("/system/bin/netcfg");
			if (netcfg.exists() == false) {
				netcfg = new File("/system/xbin/netcfg");
				if (netcfg.exists() == false) {
					return false;
				}
			}
		} catch (Exception e) {
			Utils.error("Utils","hasNetcfg: "+e.getMessage());
			return false;
		}
        return true;
	}

	 public boolean hasRootPermission() {
		 return RootCommands.rootAccessGiven();
/*		 
	    	boolean rooted = true;
			try {
				File su = new File("/system/bin/su");
				if (su.exists() == false) {
					su = new File("/system/xbin/su");
					if (su.exists() == false) {
						rooted = false;
					}
				}
			} catch (Exception e) {
				Utils.error("Utils","hasRootPermission: "+e.getMessage());
				rooted = false;
			}
			return rooted;*/
	    }
	    
	  public static void debug(String sTag, String sMsg)
	  {
			if(BuildConfig.DEBUG)
			{
				Log.d(sTag, sMsg);
			}
	  }
	  
	  
	  public static void error(String sTag, String sMsg)
	  {
			if(BuildConfig.DEBUG)
			{
				Log.e(sTag, sMsg);
			}
	  }

	public void copyFiles(final Context context)
	{
		new Thread(new Runnable(){
			public void run(){
				try
				{
					Process process = Runtime.getRuntime().exec("su");
					DataOutputStream os = new DataOutputStream(process.getOutputStream());

					//copy netcfg
					File outFile = new File("/data/data/info.lvcoffee.ethernethelper/netcfg");
					if (!outFile.exists())
					{
						Log.d(TAG,"copy netcfg");
						InputStream inStream = context.getResources().openRawResource(R.raw.netcfg);

						byte[] inbytes = new byte[inStream.available()];
						DataInputStream rtstream = new DataInputStream(inStream);
						rtstream.readFully(inbytes);
						FileOutputStream outStream = new FileOutputStream("/data/data/info.lvcoffee.ethernethelper/netcfg");
						outStream.write(inbytes);
						outStream.close();
					}
					os.writeBytes("chmod 755 /data/data/info.lvcoffee.ethernethelper/netcfg\n");
					os.writeBytes("exit\n");
					os.flush();
				}
				catch (Exception e)
				{
					Log.d(TAG,e.toString());
				}
			}
		}).start();
	}
}